﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once
#include "OwnerPtr.h"
#include "GcmpGeometryInterface.h"

#include "Vector3d.h"
#include "Intervald.h"
#include "Coordinate3d.h"
#include "GeometryErrorCode.h"

namespace gcmp
{
    /// \brief v方向的Vector3d数组定义
    typedef std::vector<Vector3d> VDirVector3dArr;
    /// \brief u方向的Vector3d的二维数组定义
    typedef std::vector<VDirVector3dArr> UDirVector3dArrArr;

    class IGeometry;
    class IArc2d;
    class IArc3d;
    class IBody;
    class ILine2d;
    class ILine3d;
    class IEllipse2d;
    class IEllipse3d;
    class IPlane;
    class IPlaneCurve3d;
    class ICurve2d;
    class ICurve3d;
    class ISpiralLine2d;
    class ISpiralLine3d;
    class NdbArchive;
    class INurbsCurve2d;
    class INurbsCurve3d;
    class IEdge;
    class IFace;
    class IPolygon;
    class ILoop;
    class IPolyCurve;
    class IPolyCurve3d;
    class ICylinder;
    class IIOStream;
    class INurbsSurface;
    class ISphere;
    class IPoint3d;
    class ITorusSurface;
    class IConicalSurface;
    class Coordinate2d;

    class GCMP_GEOMETRY_INTERFACE_EXPORT IGeometryFactory
    {
    public:
        virtual ~IGeometryFactory() {};

    public:

        /*!
        *@brief  根据字符串建立新的对象
        *@param[in] str 字符串表示
        *@return 创建的几何对象
        */
        virtual OwnerPtr<IGeometry> CreateGeometryFromString(const std::wstring &str) const = 0;

        /*!
        *@brief     根据二进制流建立新的对象
        *@param[in] archive 二进制流
        *@return    创建的几何对象
        */
        virtual OwnerPtr<IGeometry> CreateGeometryFromStream(IIOStream & ioStream) const = 0;

        /// \brief     根据二进制流化数据建立新的几何对象
        /// \param bytes 二进制流化数据
        /// \return    几何对象
        virtual OwnerPtr<IGeometry> CreateGeometryFromStreamData(const std::vector<Byte>& bytes) const = 0;

        /*!
        *@brief     根据二进制数据建立新的对象
        *@param[in] pData 二进制数据
        *@return    创建的几何对象
        */
        virtual OwnerPtr<IGeometry> CreateGeometryFromData(const char * pData) const = 0;

        /*!
        *@brief  根据起始点，终点创建二维直线段
        *@param[in] startPt    起始点
        *@param[in] endPt      终点
        *@return               二维直线段。如果起始点和终点重合，返回退化的直线
        */
        virtual OwnerPtr<ILine2d> CreateLine2d(
            const Vector2d& startPoint,
            const Vector2d& endPoint
        ) const = 0;

        /*!
        *@brief  通过基准点，直线单位化矢量方向，以及直线沿着矢量方向上的起点和终点区间，创建二维直线段
        *@param[in] position            基准点
        *@param[in] normalizedDirection 单位化的方向矢量
        *@param[in] range               起点与终点距离基点的长度范围区间
        /// \return  二维直线段。如果range长度为0，返回退化的直线
        */
        virtual OwnerPtr<ILine2d> CreateLine2d(
            const Vector2d& position,
            const Vector2d& normalizedDirection,
            const Intervald& range
        ) const = 0;

        /*!
        *@brief  根据起始点，终点创建三维直线段
        *@param[in] startPt    起始点
        *@param[in] endPt      终点
        *@return  三维直线段。如果起始点和终点重合，返回退化的直线
        */
        virtual OwnerPtr<ILine3d> CreateLine3d(
            const Vector3d& startPoint,
            const Vector3d& endPoint
        ) const = 0;

        /*!
        *@brief  通过基准点，直线单位化矢量方向，以及直线沿着矢量方向上的起点和终点区间，创建三维直线段
        *@param[in] position            基准点
        *@param[in] normalizedDirection 单位化的方向矢量
        *@param[in] range               起点与终点距离基点的长度范围区间
        /// \return  三维直线段。如果range长度为0，返回退化的直线
        */
        virtual OwnerPtr<ILine3d> CreateLine3d(
            const Vector3d& position,
            const Vector3d& normalizedDirection,
            const Intervald& range
        ) const = 0;


        /// \brief 根据坐标系、半径、参数范围、顺逆方向、半径系数构建二维螺旋线对象
        /// \param coord              螺旋线坐标系，起点位于XY平面且在X轴上
        /// \param radius             螺旋线的半径,由于容差的存在，需要大于 1E-4，否则会被认为半径为0
        /// \param range              螺旋线的参数范围
        /// \param radiusCoef         螺旋线的半径系数 含义为螺旋线的半径差/range.Length(),0代表常半径
        /// \param antiClockwise      螺旋线顺逆方向，true：逆时， false：顺时 
        /// \return 三维螺旋线
        virtual OwnerPtr<ISpiralLine2d> CreateSpiralLine2d(
            const Coordinate2d& coord,
            double radius,
            const Intervald& range,
            double radiusCoef,
            bool antiClockwise
        ) const = 0;

        /// \brief 根据坐标系、半径、参数范围、顺逆方向、高度系数、半径系数构建螺旋线对象
        /// \param coord              螺旋线坐标系，起点位于XY平面且在X轴上
        /// \param radius             螺旋线的半径,由于容差的存在，需要大于 1E-4，否则会被认为半径为0
        /// \param range              螺旋线的参数范围
        /// \param clockSign          螺旋线顺逆方向，1：逆时， -1：顺时
        /// \param heightCoef         螺旋线的高度系数 含义为螺旋线的高度/range.Length() 
        /// \param radiusCoef         螺旋线的半径系数 含义为螺旋线的半径差/range.Length(),0代表常半径
        /// \return 三维螺旋线
        virtual OwnerPtr<ISpiralLine3d> CreateSpiralLine3d(
            const Coordinate3d& coord,
            double radius,
            const Intervald& range,
            double heightCoef,
            double radiusCoef,
            bool antiClockwise
        ) const = 0;

        /// \brief 根据坐标系、起始半径、一圈的半径增量、高度增量、顺逆方向、圈数构建螺线对象，适合用户使用
        /// \param coord              坐标系，起点位于XY平面且在X轴上
        /// \param beginRadius        起始半径，必须大于0,由于容差的存在，需要大于 1E-4，否则会被认为半径为0
        /// \param radiusIncrement    半径增量，转一圈（2π）后半径改变多少
        /// \param heightIncrement    高度增量，转一圈（2π）后高度改变多少
        /// \param clockWise          螺线顺逆方向，1：逆时， -1：顺时
        /// \param numRings           旋转圈数，必须大于0，一圈代表旋转2π，注意是double类型
        /// \return 三维螺旋线
        virtual OwnerPtr<ICurve3d> CreateSpiralLine3d(
            const Coordinate3d& coord,
            double beginRadius,
            double radiusIncrement,
            double heightIncrement,
            int clockWise,
            double numRings
        ) const = 0;

        /*!
        *@brief 根据圆心、半径，参数范围，以及顺逆方向来构造圆弧
        *@param[in] rCenterPt 圆心
        *@param[in] dRadius 半径
        *@param[in] rRange 参数范围，参数意义为CIntervald(dStartAngle * dRadius * nClockSign, dEndAngle * dRadius * nClockSign)
        *@param[in] antiClockwise 顺逆方向，true：逆时， false：顺时
        */
        virtual OwnerPtr<IArc2d> CreateArc2d(
            const Vector2d & rCenterPt,
            double dRadius,
            const Intervald & rRange, 
            bool antiClockwise = true
        ) const = 0;

        /*!
        *@brief 三点确定圆弧，中垂线的交点确定圆心与半径，参考点与起始点的位置决定顺逆方向, 用户需要自己保证三点不共线
        *@param[in] rStartPt 起点坐标
        *@param[in] rEndPt 终点坐标
        *@param[in] rRefPt 参考点坐标
        */
        virtual OwnerPtr<IArc2d> CreateArc2d(
            const Vector2d & rStartPt, 
            const Vector2d& rEndPt, 
            const Vector2d& rRefPt
        )  const = 0;

        /*!
        *@brief 根据圆心、半径，起始点和终止点，以及顺逆方向来构造圆弧
        *@param[in] rCenterPt 圆心
        *@param[in] rStartPoint 起点坐标，起点与圆心的距离决定半径的大小
        *@param[in] rEndPoint 终点坐标，终点与圆心的矢量决定终止的弧度
        *@param[in] antiClockwise 顺逆方向，true：逆时， false：顺时
        */
        virtual OwnerPtr<IArc2d> CreateArc2d(
            const Vector2d & rCenterPt,
            const Vector2d & rStartPoint, 
            const Vector2d & rEndPoint, 
            bool antiClockwise
        ) const = 0;
        
        /*!
        *@brief 根据圆心、半径，起始弧度和终止弧度，以及顺逆方向来构造圆弧
        *@param[in] rCenterPt 圆心
        *@param[in] dRadius 半径
        *@param[in] dStartAngle 起始弧度
        *@param[in] dEndAngle 终止弧度
        *@param[in] antiClockwise 顺逆方向，true：逆时， false：顺时
        */
        virtual OwnerPtr<IArc2d> CreateArc2d(
            const Vector2d & rCenterPt,
            double dRadius, 
            double dStartAngle, 
            double dEndAngle, 
            bool antiClockwise
        ) const = 0;

        /*!
        *@brief  根据圆心，半径，起始弧度，终止弧度，顺时方向构造空间圆弧
        *@param[in] centerPt   坐标系原点，圆弧圆心
        *@param[in] dirX       坐标系X轴单位向量
        *@param[in] dirY       坐标系Y轴单位向量
        *@param[in] radius     圆弧半径
        *@param[in] startAngle 起始弧度
        *@param[in] endAngle   终止弧度
        *@param[in] antiClockwise  弧顺逆方向，true：逆时， false：顺时 
        */
        virtual OwnerPtr<IArc3d> CreateArc3d(
            const Vector3d & centerPt, 
            const Vector3d & dirX, 
            const Vector3d & dirY, 
            double radius, 
            double startAngle,
            double endAngle, 
            bool antiClockwise) const = 0;

        /*!
        *@brief  根据空间中三点构造空间平面圆弧曲线。三点重合或共线，内部出错
        *@param[in] const Vector3d & startPt  圆弧起点
        *@param[in] const Vector3d & endPt    圆弧终点
        *@param[in] const Vector3d & refPt    参考点   
        */
        virtual OwnerPtr<IArc3d> CreateArc3d(
            const Vector3d & startPt, 
            const Vector3d & endPt, 
            const Vector3d & refPt
         ) const = 0;

        // 用户需自己保证三点不共线!!!!!!!!!!!!!!!!!!!!!!!!!!
        /*!
        *@brief  根据空间中圆心、起点、终点和顺逆时针构造空间平面圆弧。
        *@param[in] const Vector3d & centerPt 圆弧圆心
        *@param[in] const Vector3d & startPt  圆弧起点
        *@param[in] const Vector3d & endPt    圆弧终点
        *@param[in] antiClockwise  弧顺逆方向，true：逆时， false：顺时 
        */
        virtual OwnerPtr<IArc3d> CreateArc3d(
            const Vector3d & centerPt, 
            const Vector3d & startPt,
            const Vector3d & endPt, 
            bool antiClockwise
        ) const = 0;

        /*!
        *@brief  根据圆心，X轴，Y轴，二维圆弧构造空间圆弧
        *@param[in] centerPt   坐标系原点，圆弧圆心
        *@param[in] dirX       坐标系X轴单位向量
        *@param[in] dirY       坐标系Y轴单位向量
        *@param[in] pGmIArc2d  二维圆弧
        */
        virtual OwnerPtr<IArc3d> CreateArc3d(
            const Vector3d & centerPt, 
            const Vector3d & dirX, 
            const Vector3d & dirY, 
            const IArc2d *pGmIArc2d) const = 0;

        /// \brief 根据空间中圆心、起点、终点、参考法向和顺逆时针构造空间平面圆弧
        ///
        /// \param centerPoint 圆弧圆心
        /// \param startPoint  圆弧起点
        /// \param endPoint    圆弧终点
        /// \param normal      圆弧参考法向，要求与圆弧所在平面垂直
        /// \param antiClockwise  弧顺逆方向，true：逆时针， false：顺时针
        /// \return  三维圆弧
        /// \see 要求起点和终点共圆，默认容差为1e-4；要求半径长度不能过小，默认容差为1e-4
        virtual OwnerPtr<IArc3d> CreateArc3d(
            const Vector3d & centerPoint,
            const Vector3d & startPoint,
            const Vector3d & endPoint,
            const Vector3d & normal,
            bool antiClockwise) const = 0;
   
        /*!
        * @brief     构造椭圆或椭圆弧
        * @param[in] CenterPt     中心点
        * @param[in] MajorAxis    长轴单位向量
        * @param[in] dMajorRad    长半轴
        * @param[in] dMinorRad    短半轴
        * @param[in] dStaAngle    起始角
        * @param[in] dEndAngle    终止角
        * @param[in] antiClockwise   弧顺逆方向，true：逆时， false：顺时 
        */
        virtual OwnerPtr<IEllipse2d> CreateEllipse2d(
            const Vector2d &CenterPt, 
            const Vector2d &MajorAxis, 
            double dMajorRad,
            double dMinorRad, 
            double dStaAngle, 
            double dEndAngle,
            bool antiClockwise = true
        ) const = 0;
        
        /*!
        * @brief     构造椭圆或椭圆弧
        * @param[in] CenterPt     中心点
        * @param[in] normal       法向
        * @param[in] MajorAxis    长轴单位向量
        * @param[in] dMajorRad    长半轴
        * @param[in] dMinorRad    短半轴
        * @param[in] dStaAngle    起始角
        * @param[in] dEndAngle    终止角
        * @param[in] antiClockwise   弧顺逆方向，true：逆时， false：顺时 
        */
        virtual OwnerPtr<IEllipse3d> CreateEllipse3d(
            const Vector3d &CenterPt, 
            const Vector3d &normal,
            const Vector3d &MajorAxis, 
            double dMajorRad,
            double dMinorRad, 
            double dStaAngle, 
            double dEndAngle,
            bool antiClockwise = true
        ) const = 0;

        /*!
        * @brief     构造椭圆或椭圆弧
        * @param[in] CenterPt     中心点
        * @param[in] normal       法向
        * @param[in] MajorAxis    长轴单位向量
        * @param[in] pGmEllipse2d    二维椭圆
        */
        virtual OwnerPtr<IEllipse3d> CreateEllipse3d(
            const Vector3d &CenterPt, 
            const Vector3d &normal,
            const Vector3d &MajorAxis, 
            const IEllipse2d* pGmEllipse2d
        ) const = 0;

        /*!
        @brief  根据空间中一点和法向量，以及U、V向参数域构造平面
        @param[in]  point           空间中一点
        @param[in]  normal          法向量
        @param[in]  intervalU       U向参数域
        @param[in]  intervalV       V向参数域
        @return     OwnerPtr<IPlane>  构造出的平面，如果失败返回空
        */
        virtual OwnerPtr<IPlane> CreatePlane(
            const Vector3d& point,
            const Vector3d& normal,
            const Intervald& intervalU = Intervald(Constants::MATH_NEGINFINITY, Constants::MATH_INFINITY),
            const Intervald& intervalV = Intervald(Constants::MATH_NEGINFINITY, Constants::MATH_INFINITY)
        ) const = 0;

        /*!
        @brief  根据空间中一点和以该点为原点的右手坐标系，以及U、V向参数域构造平面
        @param[in]  point           空间中一点
        @param[in]  xDir            XOY平面的x轴方向
        @param[in]  yDir            XOY平面的y轴方向
        @param[in]  intervalU       U向参数域
        @param[in]  intervalV       V向参数域
        @return     OwnerPtr<IPlane>  构造出的平面，如果失败返回空
        */
        virtual OwnerPtr<IPlane> CreatePlane(
            const Vector3d& point,
            const Vector3d& xDir,
            const Vector3d& yDir,
            const Intervald& intervalU = Intervald(Constants::MATH_NEGINFINITY, Constants::MATH_INFINITY),
            const Intervald& intervalV = Intervald(Constants::MATH_NEGINFINITY, Constants::MATH_INFINITY)
        ) const = 0;

        /*!
        *@brief  创建圆柱面（垂直拉伸，拉伸方向X轴与Y轴叉乘得到的Z轴方向）
        *@param[in] const Coordinate3d& coord        坐标系
        *@param[in] const Intervald &rRangeV         V向参数域
        *@param[in] const IArc2d* pGmIArc2d        二维圆弧曲线
        @return     OwnerPtr<ICylinder>  构造出的柱面
        */
        virtual OwnerPtr<ICylinder> CreateCylinder(
            const Coordinate3d& coord,
            const Intervald &rRangeV,
            const IArc2d* pGmIArc2d
        ) const = 0;

        /// \brief  创建球面（使用圆心，半径，世界坐标轴构造一个整球）
        /// \param center 球心
        /// \param radius 球面半径
        /// \return  球面
        virtual OwnerPtr<ISphere> CreateSphere(
            const Vector3d& center,
            double radius
        ) const = 0;

        /// \brief  创建球面（使用球面的局部坐标系，U和V向参数域和半径构建球面对象）
        /// \param coordinate 坐标系，球心在原点，北极在 Z 轴正半轴上，0 度经线在 XOZ 平面上
        /// \param limitU U向参数域，U的最小值大于等于0.0，U的最大值小于等于radius * 2PI
        /// \param limitV V向参数域，V的最小值大于等于-radius * PI/2，V的最大值小于等于radius * PI/2
        /// \param radius 球面半径
        /// \return  球面
        virtual OwnerPtr<ISphere> CreateSphere(
            const Coordinate3d& coordinate,
            const Intervald &limitU,
            const Intervald &limitV,
            double radius
        )const = 0;

        /// \brief  创建圆环面
        /// \param[in] coord 圆环面的局部坐标系，旋转轴对应 Z 轴正向，曲线的 y 向对应 Z 轴正向，曲线的 z 向对应旋转轨迹切线方向
        /// \param[in] rangeV V向参数域
        /// \param[in] pCurve2d 二维曲线
        /// \param[in] radius 旋转半径
        /// \param[in] isClockwise 是否是顺时针
        /// \return  圆环面
        virtual OwnerPtr<ITorusSurface> CreateTorusSurface(
            const gcmp::Coordinate3d& coord,
            const gcmp::Intervald& rangeV,
            const gcmp::ICurve2d* pCurve2d,
            double radius,
            bool isClockwise
        )const = 0; 
        
        /// \brief  创建圆锥面
        /// \param[in] coord 坐标系
        /// \param[in] height 高度
        /// \param[in] rangeV V向参数域
        /// \param[in] pCurve2d 二维曲线
        /// \return  圆锥面
        virtual OwnerPtr<IConicalSurface> CreateConicalSurface(
            const gcmp::Coordinate3d& coord,
            double height,
            const gcmp::Intervald& rangeV,
            const gcmp::ICurve2d* pCurve2d
        )const = 0;

        /*!
          * @brief      根据坐标系和二维曲线构造空间平面曲线
        * @param[in]  coord      坐标系
        * @param[in]  opCurve2d   二维曲线
        */
        virtual OwnerPtr<IPlaneCurve3d> CreatePlaneCurved3d(
            const Coordinate3d& coord,
            OwnerPtr<ICurve2d> opCurve2d
        ) const = 0;

        /*!
        *@brief 根据控制顶点来创建样条曲线
        *@param[in] degree 曲线次数
        *@param[in] controlPts 控制顶点数组
        *@param[in] weights 各控制顶点的权值数组，长度应与控制顶点个数相同
        *@param[in] knotVector 节点矢量，长度应等于：次数+控制顶点个数+1
        */
        virtual OwnerPtr<INurbsCurve2d> CreateNurbsCurve2d(
            int degree,
            const std::vector<Vector2d>& controlPts,
            const std::vector<double>& weights,
            const std::vector<double>& knotVector
        ) const = 0;

        /*!
        *@brief 根据控制顶点来创建样条曲线，自动计算节点矢量，且设置各控制顶点权值为1
        *@param[in] degree 曲线次数
        *@param[in] controlPts 控制顶点数组
        */
        virtual OwnerPtr<INurbsCurve2d> CreateNurbsCurve2d(
            int degree,
            const std::vector<Vector2d>& controlPts
        ) const = 0;

        /*!
        *@brief 根据插值点来创建样条曲线
        *@param[in] throughPts 插值点数组
        */
        virtual OwnerPtr<INurbsCurve2d> CreateNurbsCurve2d(const std::vector<Vector2d>& throughPts) const = 0;

        /*!
        *@brief 根据控制顶点来创建样条曲线
        *@param[in] degree 曲线次数
        *@param[in] controlPts 控制顶点数组
        *@param[in] weights 各控制顶点的权值数组，长度应与控制顶点个数相同
        *@param[in] knotVector 节点矢量，长度应等于：次数+控制顶点个数+1
        */
        virtual OwnerPtr<INurbsCurve3d> CreateNurbsCurve3d(
            int degree,
            const std::vector<Vector3d>& controlPts,
            const std::vector<double>& weights,
            const std::vector<double>& knotVector
        ) const = 0;

        /*!
        *@brief 根据控制顶点来创建样条曲线，自动计算节点矢量，且设置各控制顶点权值为1
        *@param[in] degree 曲线次数
        *@param[in] controlPts 控制顶点数组
        */
        virtual OwnerPtr<INurbsCurve3d> CreateNurbsCurve3d(
            int degree,
            const std::vector<Vector3d>& controlPts
        ) const = 0;

        /*!
        *@brief 根据插值点来创建样条曲线
        *@param[in] throughPts 插值点数组
        *@param[in] tangentVts 插值点切向量数组（数组默认为空，此时仅考虑插值点，不为空时需要和插值点数组数目相同）
        */
        virtual OwnerPtr<INurbsCurve3d> CreateNurbsCurve3d(
            const std::vector<Vector3d>& throughPts,
            const std::vector<Vector3d>& tangentVts = {}
        ) const = 0;

        /// \brief 拟合生成样条曲线, 由误差控制拟合次数和段数，算法内部根据输入点集points的弦长进行参数化
        /// \param[in] points 拟合点集
        /// \param[in] bKeepEndPoint 是否保持严格经过端点
        /// \param[in] dDistEpsilon 容差含义： 拟合容差；
        ///                         容差使用场景：对于拟合后得到三维Nurbs曲线上在插值点对应参数上的实际点与原始点points对比，两点之间距离如果小于拟合容差，曲线拟合成功；否则，拟合失败；
        ///                         容差建议dDistEpsilon = max(插值点最大模长, 曲线近似弦长 / 弧长)*相对容差
        ///                         其中相对容差不宜过小否则拟合结果容易产生局部震荡现象，相对容差建议取1e - 4以上
        /// \return 三维NURBS曲线
        virtual OwnerPtr<INurbsCurve3d> CreateNurbsCurve3dFittingWithTol(
            const std::vector<Vector3d>& points,
            bool bKeepEndPoint,
            double dDistEpsilon
        )const = 0;

        /*!
        *@brief  创建一个空的Polygon
        */
        virtual OwnerPtr<IPolygon> CreatePolygon() const = 0;

        /*!
        *@brief  创建一个IPolyCurve
        */
        virtual OwnerPtr<IPolyCurve> CreatePolyCurve(const std::vector<Vector2d>& profilePts) const = 0;

        /*!
        *@brief  创建一个空的PolyCurve
        */
        virtual OwnerPtr<IPolyCurve> CreatePolyCurve() const = 0;
       
        /*!
        *@brief  创建一个IPolyCurve
        */
        virtual OwnerPtr<IPolyCurve> CreatePolyCurve(const std::vector< OwnerPtr<ICurve2d> >& profileCurve2ds) const = 0;

        /// \brief  创建一个空的多段线IPolyCurve3d(不包含任何线)
        /// \return  多段线(不包含任何线)
        virtual OwnerPtr<IPolyCurve3d> CreatePolyCurve3d() const = 0;

        /// \brief  创建一个多段线IPolyCurve3d
        /// \param[in] profilePoints    顺序点
        /// \return  多段线
        virtual OwnerPtr<IPolyCurve3d> CreatePolyCurve3d(const std::vector<Vector3d>& profilePoints) const = 0;

        /// \brief  创建一个多段线IPolyCurve3d
        /// \param[in]  profileCurve3ds    顺序线段
        /// \return  多段线
        virtual OwnerPtr<IPolyCurve3d> CreatePolyCurve3d(const std::vector< OwnerPtr<ICurve3d> >& profileCurve3ds) const = 0;

        /// \brief  由线框体创建一组三维多段线
        /// \param[in]  pWireBody    Wire类型的体对象
        /// \param[out] opPolyCurve3ds  创建的一组三维多段线
        /// \return  错误码
        virtual GeometryErrorCode CreatePolyCurve3ds(const IBody* pWireBody, std::vector<OwnerPtr<IPolyCurve3d>>& opPolyCurve3ds) const = 0;

        /// \brief 根据三维点的位置创建点几何
        /// \param[in] position  点的位置
        /// \return 点几何
        virtual OwnerPtr<IPoint3d> CreatePoint3d(const Vector3d& position) const = 0;

        /// \brief 构造多片组合的Hermite曲面
        ///
        /// 假设有m+1个u参数，n+1个v参数，那么插值点数组分布如下（u、v向偏导，uv混合导数数组顺序类似)
        /// [0][0], [0][1], ...,   [0][n-1],  [0][n]        ---------> v向
        /// [1][0], [1][1], ...,   [1][n-1],  [1][n]        |       
        ///                                                 |
        /// [m-1][0],[m-1][1], ...,[m-1][n-1], [m-1][n]     |
        /// [m][0], [m][1], ...,   [m][n-1], [m][n]        \|/ u向
        ///
        /// \param uParameters    u方向插值点的参数
        /// \param vParameters    v方向插值点的参数
        /// \param interpolationPoints  插值点的位置
        /// \param uInterpolationPointsDerivative  插值点的u向偏导
        /// \param vInterpolationPointsDerivative  插值点的v向偏导
        /// \param uvInterpolationPointsDerivative 插值点的混合偏导
        /// \return Nurbs曲面
        virtual OwnerPtr<INurbsSurface> CreateMultiHermiteSurface(
            const std::vector<double>& uParameters,
            const std::vector<double>& vParameters,
            const UDirVector3dArrArr& interpolationPoints,
            const UDirVector3dArrArr& uInterpolationPointsDerivative,
            const UDirVector3dArrArr& vInterpolationPointsDerivative,
            const UDirVector3dArrArr& uvInterpolationPointsDerivative) const = 0;

        /// \brief  构造插值曲面
        ///
        /// 假设有m+1个u参数，n+1个v参数，那么插值点数组分布如下（u、v向偏导，uv混合导数数组顺序类似)
        /// [0][0], [0][1], ...,   [0][n-1],  [0][n]        ---------> v向
        /// [1][0], [1][1], ...,   [1][n-1],  [1][n]        |       
        ///                                                 |
        /// [m-1][0],[m-1][1], ...,[m-1][n-1], [m-1][n]     |
        /// [m][0], [m][1], ...,   [m][n-1], [m][n]        \|/ u向
        ///
        /// \param uParameters    u方向插值点的参数
        /// \param vParameters    v方向插值点的参数
        /// \param interpolationPoints  插值点的位置
        /// \return Nurbs曲面
        virtual OwnerPtr<INurbsSurface> CreateInterpolateSurface(
            const std::vector<double>& uParameters,
            const std::vector<double>& vParameters,
            const UDirVector3dArrArr& interpolationPoints) const = 0;

        /// \brief 产生四边曲面，四条曲线必须首尾连接
        /// \param pUCurve0   U向第一条曲线
        /// \param pUCurve1   U向第二条曲线
        /// \param pVCurve0   V向第一条曲线
        /// \param pVCurve1   V向第二条曲线
        /// \param dDistanceEpsilon  距离容差
        /// \return NurbsSurface
        virtual OwnerPtr<INurbsSurface> CreateFourSidedSurface(
            const ICurve3d* pUCurve0, const ICurve3d* pUCurve1,
            const ICurve3d* pVCurve0, const ICurve3d* pVCurve1, double dDistanceEpsilon)const = 0;

        /// \brief  构造Nurbs曲面
        ///
        /// 假设有m+1个u参数，n+1个v参数，那么控制点数组分布如下
        /// [0][0], [0][1], ...,   [0][n-1],  [0][n]        ---------> v向
        /// [1][0], [1][1], ...,   [1][n-1],  [1][n]        |       
        ///                                                 |
        /// [m-1][0],[m-1][1], ...,[m-1][n-1], [m-1][n]     |
        /// [m][0], [m][1], ...,   [m][n-1], [m][n]        \|/ u向
        ///
        /// \param degreeU     u方向次数
        /// \param degreeV     v方向次数
        /// \param uKnots      u方向节点向量
        /// \param vKnots      v方向节点向量
        /// \param Weights    u方向控制但点权值列表
        /// \param ctrlPoints  控制点数组
        /// \return Nurbs曲面
        virtual OwnerPtr<INurbsSurface> CreateNurbsSurface(int degreeU, int degreeV,
            int countU, int countV,
            const std::vector<double>& uKnots,
            const std::vector<double>& vKnots,
            const std::vector<double>& weights,
            const UDirVector3dArrArr& ctrlPoints) const = 0;

        /// \brief 通过控制顶点构造指定次数的周期型样条曲线。
        /// \param degree 曲线次数
        /// \param controlPoints 控制顶点集合，用户保证控制点数（首末去重之后的数量）大于次数
        /// \return 二维周期型样条曲线
        virtual OwnerPtr<INurbsCurve2d> CreatePeriodicNurbsCurve2d(int degree, std::vector<Vector2d>& controlPoints) const = 0;

        /// \brief 通过插值点构造三次的周期型样条曲线。
        /// \param throughPoints 插值点集合,用户保证非重插值点数大于1
        /// \return 二维周期型样条曲线
        virtual OwnerPtr<INurbsCurve2d> CreatePeriodicNurbsCurve2d(const std::vector<Vector2d>& throughPoints) const = 0;


        /// \brief 通过控制顶点构造指定次数的周期型样条曲线。
        /// \param degree 曲线次数
        /// \param controlPoints 控制顶点集合，用户保证控制点数（首末去重之后的数量）大于次数
        /// \return 三维周期型样条曲线
        virtual OwnerPtr<INurbsCurve3d> CreatePeriodicNurbsCurve3d(int degree, std::vector<Vector3d>& controlPoints) const = 0;

        /// \brief 通过插值点构造三次的周期型样条曲线。
        /// \param throughPoints 插值点集合,用户保证非重插值点数大于1
        /// \return 三维周期型样条曲线
        virtual OwnerPtr<INurbsCurve3d> CreatePeriodicNurbsCurve3d(const std::vector<Vector3d>& throughPoints) const = 0;


    };
}

